{
 "cells": [
  {
   "cell_type": "markdown",
   "source": [
    "# 创建数据库"
   ],
   "metadata": {
    "collapsed": false
   },
   "id": "d315f8baf3ea2b67"
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "outputs": [
    {
     "data": {
      "text/plain": "<pymilvus.milvus_client.milvus_client.MilvusClient at 0x1dc6d6e7400>"
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 导包\n",
    "from pymilvus import MilvusClient\n",
    "\n",
    "# 创建服务器连接\n",
    "client = MilvusClient(uri='http://127.0.0.1:19530')\n",
    "client"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2025-11-10T11:41:27.127087600Z",
     "start_time": "2025-11-10T11:41:27.108341500Z"
    }
   },
   "id": "4bb766966814e5e9"
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "outputs": [],
   "source": [
    "# 创建数据库\n",
    "database = client.list_databases()\n",
    "if 'milvus' not in database:\n",
    "    client.create_database(db_name='milvus')\n",
    "else:\n",
    "    client.using_database(db_name='milvus')"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2025-11-10T11:54:21.067611Z",
     "start_time": "2025-11-10T11:54:21.054553900Z"
    }
   },
   "id": "62e8585caee74ca9"
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "outputs": [],
   "source": [
    "# 创建集合\n",
    "from pymilvus import DataType\n",
    "# 定义集合的schema\n",
    "schema = client.create_schema(auto_id=True, enable_dynamic_filed=True)\n",
    "\n",
    "# 添加字段\n",
    "schema.add_field(field_name='ids', datatype=DataType.INT64, is_primary=True)\n",
    "schema.add_field(field_name='vector', datatype=DataType.FLOAT_VECTOR, dim=64)\n",
    "schema.add_field(field_name='scalar1', datatype=DataType.VARCHAR, max_length=256, description='标量字段')\n",
    "\n",
    "# 将schema添加到数据库中\n",
    "client.create_collection(collection_name='demo_v1', schema=schema)"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2025-11-10T11:59:15.680649600Z",
     "start_time": "2025-11-10T11:59:15.662428400Z"
    }
   },
   "id": "2a1e3169cb5923"
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "outputs": [
    {
     "data": {
      "text/plain": "['vector_index']"
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 设置索引\n",
    "index_params = client.prepare_index_params()\n",
    "\n",
    "# 添加索引\n",
    "index_params.add_index(field_name='vector', metric_type='COSINE', index_type='', index_name='vector_index')\n",
    "client.create_index(collection_name='demo_v1', index_params=index_params)\n",
    "\n",
    "# 查看索引\n",
    "res = client.list_indexes(collection_name='demo_v1')\n",
    "res"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2025-11-10T12:00:53.036073300Z",
     "start_time": "2025-11-10T12:00:52.486156Z"
    }
   },
   "id": "4f109fcaecf8958"
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "outputs": [
    {
     "data": {
      "text/plain": "['vector_index', 'scalar1_index']"
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 给标量设置索引\n",
    "index_params.add_index(field_name='scalar1', index_type='', index_name='scalar1_index')\n",
    "client.create_index(collection_name='demo_v1', index_params=index_params)\n",
    "res = client.list_indexes(collection_name='demo_v1')\n",
    "res"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2025-11-10T12:08:14.923940100Z",
     "start_time": "2025-11-10T12:08:13.853680600Z"
    }
   },
   "id": "b928935af78b3a44"
  },
  {
   "cell_type": "markdown",
   "source": [
    "## Entity实体数据操作\n",
    "在 Milvus 中，实体**指的是**Collections**中共享相同**Schema 的数据记录，行中每个字段的数据构成一个实体。因此，同一 Collections 中的实体具有相同的属性（如字段名称、数据类型和其他约束）。"
   ],
   "metadata": {
    "collapsed": false
   },
   "id": "b77832066d52801d"
  },
  {
   "cell_type": "markdown",
   "source": [
    "## 数据的增删改"
   ],
   "metadata": {
    "collapsed": false
   },
   "id": "df5b23a2d91bb1c9"
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "outputs": [
    {
     "data": {
      "text/plain": "{'insert_count': 10, 'ids': [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], 'cost': 0}"
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 先建一个表\n",
    "client.create_collection(collection_name='demo_v2', dimension=5, metric_type='IP')\n",
    "data = [\n",
    "    {\"id\": 0, \"vector\": [0.3580376395471989, -0.6023495712049978, 0.18414012509913835, -0.26286205330961354,\n",
    "                         0.9029438446296592], \"color\": \"pink_8682\"},\n",
    "    {\"id\": 1, \"vector\": [0.19886812562848388, 0.06023560599112088, 0.6976963061752597, 0.2614474506242501,\n",
    "                         0.838729485096104], \"color\": \"red_7025\"},\n",
    "    {\"id\": 2, \"vector\": [0.43742130801983836, -0.5597502546264526, 0.6457887650909682, 0.7894058910881185,\n",
    "                         0.20785793220625592], \"color\": \"orange_6781\"},\n",
    "    {\"id\": 3, \"vector\": [0.3172005263489739, 0.9719044792798428, -0.36981146090600725, -0.4860894583077995,\n",
    "                         0.95791889146345], \"color\": \"pink_9298\"},\n",
    "    {\"id\": 4, \"vector\": [0.4452349528804562, -0.8757026943054742, 0.8220779437047674, 0.46406290649483184,\n",
    "                         0.30337481143159106], \"color\": \"red_4794\"},\n",
    "    {\"id\": 5, \"vector\": [0.985825131989184, -0.8144651566660419, 0.6299267002202009, 0.1206906911183383,\n",
    "                         -0.1446277761879955], \"color\": \"yellow_4222\"},\n",
    "    {\"id\": 6, \"vector\": [0.8371977790571115, -0.015764369584852833, -0.31062937026679327, -0.562666951622192,\n",
    "                         -0.8984947637863987], \"color\": \"red_9392\"},\n",
    "    {\"id\": 7, \"vector\": [-0.33445148015177995, -0.2567135004164067, 0.8987539745369246, 0.9402995886420709,\n",
    "                         0.5378064918413052], \"color\": \"grey_8510\"},\n",
    "    {\"id\": 8, \"vector\": [0.39524717779832685, 0.4000257286739164, -0.5890507376891594, -0.8650502298996872,\n",
    "                         -0.6140360785406336], \"color\": \"white_9381\"},\n",
    "    {\"id\": 9, \"vector\": [0.5718280481994695, 0.24070317428066512, -0.3737913482606834, -0.06726932177492717,\n",
    "                         -0.6980531615588608], \"color\": \"purple_4976\"}\n",
    "]\n",
    "\n",
    "# 添加数据\n",
    "res = client.insert(collection_name='demo_v2', data=data)\n",
    "res"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2025-11-10T12:12:16.983948300Z",
     "start_time": "2025-11-10T12:12:14.229702100Z"
    }
   },
   "id": "b7ec832089f58933"
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "outputs": [
    {
     "data": {
      "text/plain": "{'insert_count': 10, 'ids': [10, 11, 12, 13, 14, 15, 16, 17, 18, 19], 'cost': 0}"
     },
     "execution_count": 19,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 在指定分区添加数据\n",
    "data = [\n",
    "    {\"id\": 10, \"vector\": [-0.5570353903748935, -0.8997887893201304, -0.7123782431855732, -0.6298990746450119,\n",
    "                          0.6699215060604258], \"color\": \"red_1202\"},\n",
    "    {\"id\": 11, \"vector\": [0.6319019033373907, 0.6821488267878275, 0.8552303045704168, 0.36929791364943054,\n",
    "                          -0.14152860714878068], \"color\": \"blue_4150\"},\n",
    "    {\"id\": 12, \"vector\": [0.9483947484855766, -0.32294203351925344, 0.9759290319978025, 0.8262982148666174,\n",
    "                          -0.8351194181285713], \"color\": \"orange_4590\"},\n",
    "    {\"id\": 13, \"vector\": [-0.5449109892498731, 0.043511240563786524, -0.25105249484790804, -0.012030655265886425,\n",
    "                          -0.0010987671273892108], \"color\": \"pink_9619\"},\n",
    "    {\"id\": 14, \"vector\": [0.6603339372951424, -0.10866551787442225, -0.9435597754324891, 0.8230244263466688,\n",
    "                          -0.7986720938400362], \"color\": \"orange_4863\"},\n",
    "    {\"id\": 15, \"vector\": [-0.8825129181091456, -0.9204557711667729, -0.935350065513425, 0.5484069690287079,\n",
    "                          0.24448151140671204], \"color\": \"orange_7984\"},\n",
    "    {\"id\": 16, \"vector\": [0.6285586391568163, 0.5389064528263487, -0.3163366239905099, 0.22036279378888013,\n",
    "                          0.15077052220816167], \"color\": \"blue_9010\"},\n",
    "    {\"id\": 17, \"vector\": [-0.20151825016059233, -0.905239387635804, 0.6749305353372479, -0.7324272081377843,\n",
    "                          -0.33007998971889263], \"color\": \"blue_4521\"},\n",
    "    {\"id\": 18, \"vector\": [0.2432286610792349, 0.01785636564206139, -0.651356982731391, -0.35848148851027895,\n",
    "                          -0.7387383128324057], \"color\": \"orange_2529\"},\n",
    "    {\"id\": 19, \"vector\": [0.055512329053363674, 0.7100266349039421, 0.4956956543575197, 0.24541352586717702,\n",
    "                          0.4209030729923515], \"color\": \"red_9437\"}\n",
    "]\n",
    "\n",
    "client.create_partition(collection_name='demo_v2', partition_name='partitionA')\n",
    "res = client.insert(collection_name='demo_v2', partition_name='partitionA', data=data)\n",
    "res"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2025-11-10T12:15:16.007851200Z",
     "start_time": "2025-11-10T12:15:15.975732800Z"
    }
   },
   "id": "82dc434293b8125"
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "outputs": [
    {
     "data": {
      "text/plain": "{'upsert_count': 10, 'cost': 0}"
     },
     "execution_count": 20,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# upsert若数据不存在，则直接创建并保存到数据库，若数据存在则覆盖原数据\n",
    "data = [\n",
    "    {\"id\": 0, \"vector\": [-0.619954382375778, 0.4479436794798608, -0.17493894838751745, -0.4248030059917294,\n",
    "                         -0.8648452746018911], \"color\": \"black_9898\"},\n",
    "    {\"id\": 1, \"vector\": [0.4762662251462588, -0.6942502138717026, -0.4490002642657902, -0.628696575798281,\n",
    "                         0.9660395877041965], \"color\": \"red_7319\"},\n",
    "    {\"id\": 2, \"vector\": [-0.8864122635045097, 0.9260170474445351, 0.801326976181461, 0.6383943392381306,\n",
    "                         0.7563037341572827], \"color\": \"white_6465\"},\n",
    "    {\"id\": 3, \"vector\": [0.14594326235891586, -0.3775407299900644, -0.3765479013078812, 0.20612075380355122,\n",
    "                         0.4902678929632145], \"color\": \"orange_7580\"},\n",
    "    {\"id\": 4, \"vector\": [0.4548498669607359, -0.887610217681605, 0.5655081329910452, 0.19220509387904117,\n",
    "                         0.016513983433433577], \"color\": \"red_3314\"},\n",
    "    {\"id\": 5, \"vector\": [0.11755001847051827, -0.7295149788999611, 0.2608115847524266, -0.1719167007897875,\n",
    "                         0.7417611743754855], \"color\": \"black_9955\"},\n",
    "    {\"id\": 6, \"vector\": [0.9363032158314308, 0.030699901477745373, 0.8365910312319647, 0.7823840208444011,\n",
    "                         0.2625222076909237], \"color\": \"yellow_2461\"},\n",
    "    {\"id\": 7, \"vector\": [0.0754823906014721, -0.6390658668265143, 0.5610517334334937, -0.8986261118798251,\n",
    "                         0.9372056764266794], \"color\": \"white_5015\"},\n",
    "    {\"id\": 8, \"vector\": [-0.3038434006935904, 0.1279149203380523, 0.503958664270957, -0.2622661156746988,\n",
    "                         0.7407627307791929], \"color\": \"purple_6414\"},\n",
    "    {\"id\": 9, \"vector\": [-0.7125086947677588, -0.8050968321012257, -0.32608864121785786, 0.3255654958645424,\n",
    "                         0.26227968923834233], \"color\": \"brown_7231\"}\n",
    "]\n",
    "\n",
    "res = client.upsert(collection_name='demo_v2', data=data)\n",
    "res"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2025-11-10T12:17:11.884010500Z",
     "start_time": "2025-11-10T12:17:11.848494500Z"
    }
   },
   "id": "73bfe347f40ae68e"
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "outputs": [
    {
     "data": {
      "text/plain": "{'delete_count': 4, 'cost': 0}"
     },
     "execution_count": 21,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 删除数据，使用delete直接通过filter删除指定id，不存在则不受影响\n",
    "# filter接收值为字符串\n",
    "res = client.delete(collection_name='demo_v2', filter='id in [1, 3, 15, 22]')\n",
    "res\n",
    "# 删除了1, 3, 15"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2025-11-10T12:18:53.178007Z",
     "start_time": "2025-11-10T12:18:53.114492Z"
    }
   },
   "id": "a1d74b0c2967fd90"
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "outputs": [
    {
     "data": {
      "text/plain": "{'delete_count': 4, 'cost': 0}"
     },
     "execution_count": 24,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 删除指定分区的数据\n",
    "# ids接收值为列表\n",
    "res = client.delete(\n",
    "    collection_name='demo_v2',\n",
    "    ids=[2, 4, 11, 21],\n",
    "    partition_name='partitionA'\n",
    ")\n",
    "res\n",
    "# 只删除了11"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2025-11-10T12:21:11.014165900Z",
     "start_time": "2025-11-10T12:21:10.959622100Z"
    }
   },
   "id": "9d4ddeded022a733"
  },
  {
   "cell_type": "markdown",
   "source": [
    "## 数据查询"
   ],
   "metadata": {
    "collapsed": false
   },
   "id": "b97777c7e3a4cc6d"
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "res --> data: [\"[{'id': 2, 'distance': 0.6215222477912903, 'entity': {'id': 2, 'vector': [-0.8864122629165649, 0.9260170459747314, 0.8013269901275635, 0.6383943557739258, 0.7563037276268005]}}, {'id': 6, 'distance': 0.5434917211532593, 'entity': {'id': 6, 'vector': [0.9363031983375549, 0.030699901282787323, 0.8365910053253174, 0.7823840379714966, 0.26252222061157227]}}]\"]\n",
      "\n",
      "res[0] --> [{'id': 2, 'distance': 0.6215222477912903, 'entity': {'id': 2, 'vector': [-0.8864122629165649, 0.9260170459747314, 0.8013269901275635, 0.6383943557739258, 0.7563037276268005]}}, {'id': 6, 'distance': 0.5434917211532593, 'entity': {'id': 6, 'vector': [0.9363031983375549, 0.030699901282787323, 0.8365910053253174, 0.7823840379714966, 0.26252222061157227]}}]\n",
      "\n",
      "res[0][0] --> {'id': 2, 'distance': 0.6215222477912903, 'entity': {'id': 2, 'vector': [-0.8864122629165649, 0.9260170459747314, 0.8013269901275635, 0.6383943557739258, 0.7563037276268005]}}\n"
     ]
    }
   ],
   "source": [
    "# 参数解析\n",
    "# collocation_name:集合名词\n",
    "# data:查询向量\n",
    "# limit:返回值数量\n",
    "# output_fields:返回字段\n",
    "# search_params:搜索参数\n",
    "res = client.search(\n",
    "    collection_name='demo_v2',\n",
    "    data=[[0.13232342, 0.31324213, 0.312312344, 0.14231123123, 0.1423142131421]],\n",
    "    limit=2,\n",
    "    search_params={'metric_type': 'IP', 'params': {}},\n",
    "    output_fields=['id', 'vector']\n",
    ")\n",
    "print(f'res --> {res}', end='\\n\\n')\n",
    "print(f'res[0] --> {res[0]}', end='\\n\\n')\n",
    "print(f'res[0][0] --> {res[0][0]}', end='\\n\\n')"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2025-11-10T12:30:07.827506500Z",
     "start_time": "2025-11-10T12:30:07.796090Z"
    }
   },
   "id": "5da0d238bb3c0f8d"
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "outputs": [
    {
     "data": {
      "text/plain": "data: [\"[{'id': 2, 'distance': 1.239823818206787, 'entity': {'id': 2, 'color': 'white_6465'}}, {'id': 6, 'distance': 1.1964739561080933, 'entity': {'id': 6, 'color': 'yellow_2461'}}]\", \"[{'id': 16, 'distance': 0.8774394989013672, 'entity': {'id': 16, 'color': 'blue_9010'}}, {'id': 19, 'distance': 0.8082706928253174, 'entity': {'id': 19, 'color': 'red_9437'}}]\"]"
     },
     "execution_count": 31,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 多向量查询\n",
    "res = client.search(\n",
    "    collection_name='demo_v2',\n",
    "    data=[[0.19886812562848388, 0.06023560599112088, 0.6976963061752597, 0.2614474506242501,\n",
    "           0.838729485096104],\n",
    "          [0.3172005263489739, 0.9719044792798428, -0.36981146090600725, -0.4860894583077995,\n",
    "           0.95791889146345]],\n",
    "    limit=2,\n",
    "    output_fields=['id', 'color'],\n",
    "    search_params={'metric_type': 'IP', 'params':{}}\n",
    ")\n",
    "res"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2025-11-10T12:41:09.120437100Z",
     "start_time": "2025-11-10T12:41:09.090394800Z"
    }
   },
   "id": "56ea63bdf2bccd08"
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "outputs": [
    {
     "data": {
      "text/plain": "data: [\"[{'id': 19, 'distance': 0.8168401122093201, 'entity': {'id': 19, 'color': 'red_9437', 'vector': [0.05551232770085335, 0.7100266218185425, 0.49569565057754517, 0.24541352689266205, 0.4209030866622925]}}, {'id': 12, 'distance': 0.3656492531299591, 'entity': {'id': 12, 'color': 'orange_4590', 'vector': [0.948394775390625, -0.3229420483112335, 0.9759290218353271, 0.8262982368469238, -0.8351194262504578]}}]\", \"[{'id': 16, 'distance': 0.8774394989013672, 'entity': {'id': 16, 'color': 'blue_9010', 'vector': [0.6285586357116699, 0.538906455039978, -0.31633663177490234, 0.2203627973794937, 0.15077051520347595]}}, {'id': 19, 'distance': 0.8082706928253174, 'entity': {'id': 19, 'color': 'red_9437', 'vector': [0.05551232770085335, 0.7100266218185425, 0.49569565057754517, 0.24541352689266205, 0.4209030866622925]}}]\"]"
     },
     "execution_count": 30,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 分区查找\n",
    "res = client.search(\n",
    "    collection_name='demo_v2',\n",
    "    data=[[0.19886812562848388, 0.06023560599112088, 0.6976963061752597, 0.2614474506242501,\n",
    "       0.838729485096104],\n",
    "      [0.3172005263489739, 0.9719044792798428, -0.36981146090600725, -0.4860894583077995,\n",
    "       0.95791889146345]],\n",
    "    output_fields=['id', 'color', 'vector'],\n",
    "    limit=2,\n",
    "    partition_names=['partitionA']\n",
    ")\n",
    "res"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2025-11-10T12:37:05.319127500Z",
     "start_time": "2025-11-10T12:37:05.298552500Z"
    }
   },
   "id": "40192bb393a9e9d6"
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "outputs": [
    {
     "data": {
      "text/plain": "data: [\"[{'id': 19, 'distance': 0.8168401122093201, 'entity': {'id': 19, 'color': 'red_9437'}}, {'id': 4, 'distance': 0.4956446588039398, 'entity': {'id': 4, 'color': 'red_3314'}}, {'id': 10, 'distance': -0.26480212807655334, 'entity': {'id': 10, 'color': 'red_1202'}}]\"]"
     },
     "execution_count": 32,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 过滤搜索\n",
    "# 过滤器搜索：筛选搜索将标量筛选器应用于矢量搜索，允许我们根据特定条件优化搜索结果。\n",
    "# 例如：根据字符串模式优化搜索结果，可以使用like运算符。此运算符通过考虑前缀、中缀和后缀来启动字符串匹配：\n",
    "# 筛选颜色以红色为前缀的结果：\n",
    "res = client.search(\n",
    "    collection_name='demo_v2',\n",
    "    data=[[0.19886812562848388, 0.06023560599112088, 0.6976963061752597, 0.2614474506242501,\n",
    "       0.838729485096104]],\n",
    "    limit=5,\n",
    "    search_params={'metric': 'IP', 'params': {}},\n",
    "    filter='color like \"red%\"',\n",
    "    output_fields=['id', 'color']\n",
    ")\n",
    "res"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2025-11-10T12:48:23.306305700Z",
     "start_time": "2025-11-10T12:48:23.240833100Z"
    }
   },
   "id": "60e5208abdd9e18f"
  },
  {
   "cell_type": "code",
   "execution_count": 43,
   "outputs": [
    {
     "data": {
      "text/plain": "'[\\n    [\\n        {\\n            \"id\": 7,\\n            \"distance\": 0.9190787672996521,\\n            \"entity\": {\\n                \"id\": 7,\\n                \"vector\": [\\n                    0.07548239082098007,\\n                    -0.6390658617019653,\\n                    0.5610517263412476,\\n                    -0.8986260890960693,\\n                    0.9372056722640991\\n                ]\\n            }\\n        },\\n        {\\n            \"id\": 8,\\n            \"distance\": 0.8516210913658142,\\n            \"entity\": {\\n                \"id\": 8,\\n                \"vector\": [\\n                    -0.3038434088230133,\\n                    0.1279149204492569,\\n                    0.5039586424827576,\\n                    -0.2622661292552948,\\n                    0.7407627105712891\\n                ]\\n            }\\n        },\\n        {\\n            \"id\": 19,\\n            \"distance\": 0.8168401122093201,\\n            \"entity\": {\\n                \"id\": 19,\\n                \"vector\": [\\n                    0.05551232770085335,\\n                    0.7100266218185425,\\n                    0.49569565057754517,\\n                    0.24541352689266205,\\n                    0.4209030866622925\\n                ]\\n            }\\n        }\\n    ]\\n]'"
     },
     "execution_count": 43,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 范围搜索\n",
    "# 范围搜索允许查找距离查询向量指定距离范围内的向量\n",
    "# 范围搜索radius：定义搜索空间的外边界，只有距离查询向量在此距离内的向量才能被视为潜在匹配。\n",
    "# range_filter：虽然radius设置搜索的外部限制，但可以选择使用range_filter来定义内部边界，创建一个距离范围，在该范围下向量必须落下才能被视为匹配。\n",
    "import json\n",
    "\n",
    "search_params = {\n",
    "    'metric': 'IP',\n",
    "    'params':{\n",
    "        'radius': 0.8,\n",
    "        'range_filter': 1\n",
    "    }\n",
    "}\n",
    "\n",
    "res = client.search(\n",
    "    collection_name='demo_v2',\n",
    "    data=[[0.19886812562848388, 0.06023560599112088, 0.6976963061752597, 0.2614474506242501,\n",
    "       0.838729485096104]],\n",
    "    limit=10,\n",
    "    search_params=search_params,\n",
    "    output_fields=['id', 'vector']\n",
    ")\n",
    "result = json.dumps(res, indent=4)\n",
    "result\n"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2025-11-10T13:02:04.556356200Z",
     "start_time": "2025-11-10T13:02:04.511484900Z"
    }
   },
   "id": "6decff9a7ae44472"
  },
  {
   "cell_type": "code",
   "execution_count": 44,
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[ 0.07548239 -0.63906586  0.56105173 -0.89862609  0.93720567]\n"
     ]
    }
   ],
   "source": [
    "import numpy as np\n",
    "print(np.array(res[0][0]['entity']['vector']))"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2025-11-10T13:02:05.503916200Z",
     "start_time": "2025-11-10T13:02:05.463847200Z"
    }
   },
   "id": "ba6faa664a44e54e"
  },
  {
   "cell_type": "markdown",
   "source": [
    "## 复杂查询\n",
    "* 混合检索：要对两组 ANN 搜索结果进行合并和重新排序，有必要选择适当的重新排序策略。支持两种重排策略：加权排名策略（WeightedRanker）和**重排序策略**（RRFRanker）。在选择重排策略时，需要考虑的一个问题是，在向量场中是否需要强调一个或多个基本 ANN 搜索。\n",
    "* 加权排名：如果您要求结果强调特定的向量场，建议使用该策略。通过 WeightedRanker，您可以为某些向量场分配更高的权重，从而更加强调这些向量场。例如，在多模态搜索中，图片的文字描述可能比图片的颜色更重要。"
   ],
   "metadata": {
    "collapsed": false
   },
   "id": "62bba0259aac64d7"
  },
  {
   "cell_type": "code",
   "execution_count": 47,
   "outputs": [
    {
     "data": {
      "text/plain": "{'insert_count': 1000, 'ids': [7845, 5275, 5228, 6016, 8474, 8848, 6927, 3074, 7043, 229, 3682, 9062, 4411, 458, 2121, 1331, 1791, 4801, 9088, 924, 4269, 5114, 3415, 1094, 6243, 9162, 7911, 9690, 9057, 1329, 7669, 3541, 8979, 9092, 898, 8384, 8964, 2364, 2497, 9067, 9602, 6756, 1880, 3374, 2813, 8618, 6436, 570, 9786, 9699, 8695, 7610, 4765, 3416, 1235, 8254, 5282, 2375, 566, 4145, 683, 5673, 940, 3325, 9522, 742, 6421, 7398, 7978, 1096, 9933, 3223, 1000, 1199, 5493, 9995, 5665, 7448, 6790, 6284, 7713, 9026, 3715, 307, 6015, 6924, 7414, 423, 1608, 4521, 1998, 4127, 5255, 2658, 3433, 3792, 8232, 2989, 2176, 5479, 8567, 8939, 302, 6246, 8504, 650, 8943, 3487, 3726, 9172, 6657, 7335, 5600, 5671, 6114, 9883, 3500, 5457, 557, 4066, 3848, 837, 3649, 8815, 8620, 7401, 3207, 5558, 8101, 8406, 4462, 9632, 5583, 886, 6674, 8576, 5912, 111, 2239, 7043, 5521, 6698, 9399, 5639, 5241, 2284, 8729, 2128, 6384, 8687, 8320, 9394, 5089, 2393, 7079, 9970, 418, 4535, 822, 3049, 351, 3272, 6694, 1908, 1007, 564, 4446, 795, 4352, 4333, 4252, 7461, 4029, 1245, 3739, 1370, 5549, 1749, 5788, 2624, 6448, 4264, 6626, 1433, 1370, 2990, 3520, 2234, 3272, 8618, 9777, 9779, 448, 1220, 9393, 2138, 209, 7622, 8570, 5807, 1749, 3459, 2902, 5466, 266, 626, 6292, 8983, 1242, 5290, 3095, 9557, 5381, 9269, 9366, 2267, 299, 116, 3808, 692, 9500, 8693, 5273, 6049, 5197, 2037, 4166, 2941, 3479, 342, 8747, 1054, 5566, 6480, 8521, 1579, 629, 7860, 6524, 3381, 3353, 687, 618, 151, 2066, 8633, 3857, 5471, 6592, 1462, 1159, 7254, 3646, 6517, 6728, 1763, 6067, 7751, 7506, 2981, 2039, 7255, 5524, 4103, 8413, 5173, 8878, 702, 9314, 1297, 2842, 3498, 5818, 3724, 2043, 4647, 8459, 5218, 8506, 6081, 7802, 6878, 602, 4157, 7801, 7219, 8080, 1638, 6356, 5959, 9356, 1867, 6106, 5086, 6117, 4685, 3725, 7722, 9929, 8264, 7376, 9458, 8664, 620, 2976, 7160, 1856, 9106, 705, 477, 1943, 8400, 8540, 2293, 7532, 5076, 7677, 6020, 8787, 2389, 4970, 7542, 4862, 2269, 7073, 5555, 9625, 260, 4447, 6723, 3340, 1454, 7623, 254, 1278, 8228, 4201, 7458, 7857, 347, 6682, 5105, 7566, 6507, 8379, 6017, 7260, 6634, 5020, 4730, 2892, 3648, 9721, 6107, 910, 698, 9816, 6725, 5546, 6794, 8445, 7169, 3526, 3100, 2256, 3517, 1063, 6605, 1, 8625, 8948, 2139, 6305, 5021, 2900, 5749, 5828, 3909, 5452, 7026, 108, 4625, 7964, 7057, 9661, 3832, 8646, 156, 1996, 7586, 5797, 6956, 7828, 1071, 1514, 7129, 3060, 2374, 6389, 9771, 5287, 6108, 6186, 3522, 8562, 9587, 4811, 1302, 1650, 2345, 9989, 6656, 3117, 8988, 4883, 5439, 1441, 447, 5867, 7550, 6248, 98, 37, 1988, 2128, 3416, 5861, 6992, 6526, 4871, 4094, 5914, 9069, 6214, 4459, 758, 2921, 131, 5283, 822, 4633, 8241, 5037, 9971, 6971, 2721, 1200, 8469, 7463, 504, 6653, 2851, 8648, 6593, 4226, 2276, 1707, 3987, 3153, 1762, 5438, 205, 2076, 3814, 327, 2882, 1279, 3382, 4419, 2617, 1245, 6395, 7101, 7160, 5806, 6554, 9004, 1845, 7387, 4853, 360, 5233, 499, 4108, 2574, 6740, 9199, 4785, 8774, 3539, 2706, 6677, 2954, 1357, 7871, 1013, 1053, 5226, 3573, 5757, 783, 1324, 332, 5895, 6865, 2232, 9755, 7212, 2254, 338, 8154, 4134, 578, 1728, 2965, 2222, 3805, 7223, 5664, 3578, 9695, 8032, 9725, 2373, 4844, 4048, 270, 117, 3891, 7011, 1778, 2122, 4707, 1320, 8404, 8155, 751, 417, 420, 507, 8404, 9972, 6992, 5033, 2767, 6017, 5220, 3336, 9047, 221, 3333, 7638, 7787, 4310, 5973, 9315, 7270, 6186, 8499, 6162, 3169, 8000, 1232, 9606, 1184, 6167, 1898, 90, 1477, 3542, 893, 4622, 8078, 1121, 4976, 1791, 6197, 2120, 290, 6585, 8177, 7836, 7132, 5627, 713, 3866, 952, 5560, 9667, 6291, 9706, 2773, 8821, 5289, 7445, 7613, 9774, 3984, 8679, 3965, 889, 4421, 6970, 5268, 734, 3696, 4856, 819, 6881, 3294, 1210, 1130, 4485, 2259, 9824, 7758, 6972, 2217, 202, 7195, 4946, 7872, 5236, 7728, 2688, 6054, 9551, 5076, 5770, 8876, 6261, 4863, 3410, 7180, 9379, 1269, 7167, 2029, 5272, 4639, 9687, 6326, 9828, 6759, 1638, 5398, 2569, 9468, 8252, 6003, 3007, 8076, 2712, 2328, 9602, 7765, 5411, 2574, 819, 2426, 10000, 3654, 2830, 8288, 9860, 7601, 3035, 6362, 8177, 6552, 6889, 9215, 3091, 6439, 482, 3497, 4510, 4597, 3893, 9497, 2581, 1061, 3876, 3232, 5889, 3730, 4438, 8543, 2149, 59, 9321, 4065, 9739, 6870, 9270, 9639, 3595, 2530, 5759, 3042, 5709, 1978, 899, 413, 6997, 1817, 795, 479, 238, 9542, 5850, 912, 1532, 9181, 6560, 765, 3290, 5027, 6867, 8014, 2202, 1613, 4846, 4129, 773, 7391, 8320, 4080, 7108, 9215, 6103, 5406, 5258, 9265, 430, 9267, 4768, 3344, 533, 93, 4947, 27, 6073, 3585, 4790, 8843, 5095, 5745, 8420, 9672, 1881, 6526, 3075, 4969, 8631, 4370, 4596, 3479, 313, 3239, 3646, 2973, 6670, 147, 6634, 2180, 6277, 3051, 7954, 2452, 3965, 7358, 5935, 8118, 4269, 3580, 4347, 4860, 7933, 195, 7734, 7459, 803, 9463, 5211, 7218, 6456, 3475, 5760, 3400, 183, 9697, 6808, 4686, 4813, 3389, 5150, 9643, 720, 5185, 4169, 134, 4832, 8138, 9614, 4901, 9339, 4668, 7309, 3019, 2098, 296, 8450, 4291, 1198, 2015, 8094, 5073, 7803, 6032, 4163, 299, 6148, 9985, 1314, 1591, 8030, 7126, 297, 4634, 327, 8361, 1190, 6135, 220, 2190, 381, 6349, 3801, 6379, 7128, 1194, 2719, 3783, 2670, 3121, 6352, 5345, 927, 9790, 9169, 7286, 3536, 5705, 6296, 5889, 6091, 7299, 5947, 8910, 6062, 3167, 3251, 7809, 2696, 6538, 5778, 987, 7042, 114, 852, 432, 5660, 3065, 189, 6784, 8233, 2561, 6328, 4159, 8978, 2602, 5782, 9527, 725, 8757, 2745, 3246, 2004, 3693, 1860, 5775, 2609, 1023, 9289, 6858, 1951, 8080, 307, 9402, 8600, 4268, 8315, 8497, 6138, 7013, 3585, 8063, 8834, 3413, 2783, 5043, 8941, 2989, 4347, 6117, 1462, 7836, 244, 1987, 3130, 1622, 4487, 6156, 8136, 843, 8409, 8823, 555, 892, 6777, 9421, 4100, 618, 5138, 1855, 2398, 5877, 4612, 2314, 5875, 9186, 7284, 6662, 5175, 6907, 6077, 8714, 4116, 8432, 7042, 1706, 2762, 6255, 2681, 3650, 6065, 424, 5417, 7296, 4968, 2740, 361, 414, 2298, 6128, 3943, 3198, 5762, 5834, 4036, 2361, 6205, 2820, 9903, 7869, 1204, 8014, 3295, 2975, 866, 4623, 8550, 8348, 511, 9815, 9340, 4542, 6873, 6719, 9110, 2859, 7585, 8894, 6984, 7553, 3482, 4565, 6527, 7460], 'cost': 0}"
     },
     "execution_count": 47,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import random\n",
    "from pymilvus import RRFRanker\n",
    "\n",
    "ranker = RRFRanker(100)\n",
    "\n",
    "# 定义schema\n",
    "schema = client.create_schema(enable_dynamic_field=False)\n",
    "schema.add_field(\n",
    "    field_name='film_id',\n",
    "    datatype=DataType.INT64,\n",
    "    is_primary=True\n",
    ")\n",
    "schema.add_field(\n",
    "    field_name='film_vector',\n",
    "    datatype=DataType.FLOAT_VECTOR,\n",
    "    dim=5\n",
    ")\n",
    "schema.add_field(\n",
    "    field_name='poster_vector',\n",
    "    datatype=DataType.FLOAT_VECTOR,\n",
    "    dim=5\n",
    ")\n",
    "\n",
    "# 定义索引\n",
    "index_params = client.prepare_index_params()\n",
    "index_params.add_index(\n",
    "    field_name='film_vector',\n",
    "    index_type='IVF_FLAT',\n",
    "    metric_type='L2',\n",
    "    params={'nlist': 128}\n",
    ")\n",
    "index_params.add_index(\n",
    "    field_name='poster_vector',\n",
    "    index_type='',\n",
    "    metric_type='COSINE'\n",
    ")\n",
    "# 创建集合\n",
    "client.create_collection(\n",
    "    collection_name='demo_v3',\n",
    "    schema=schema,\n",
    "    index_params=index_params\n",
    ")\n",
    "\n",
    "# 向量库插入实体\n",
    "entities = []\n",
    "for _ in range(1000):\n",
    "    # 构造实体\n",
    "    film_id = random.randint(1, 10000)\n",
    "    film_vector = [random.random() for _ in range(5)]\n",
    "    poster_vector = [random.random() for _ in range(5)]\n",
    "    entity = {\n",
    "        'film_id': film_id,\n",
    "        'film_vector': film_vector,\n",
    "        'poster_vector': poster_vector\n",
    "    }\n",
    "    entities.append(entity)\n",
    "\n",
    "# 插入数据表中\n",
    "res = client.insert(collection_name='demo_v3', data=entities)\n",
    "res"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2025-11-10T13:16:46.903627200Z",
     "start_time": "2025-11-10T13:16:45.807806600Z"
    }
   },
   "id": "3ecaf93d4de27461"
  },
  {
   "cell_type": "code",
   "execution_count": 52,
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "TopK result:\n",
      "{'id': 4862, 'distance': 0.009900989942252636, 'entity': {}}\n",
      "{'id': 7180, 'distance': 0.009900989942252636, 'entity': {}}\n",
      "{'id': 2039, 'distance': 0.009803921915590763, 'entity': {}}\n",
      "{'id': 6044, 'distance': 0.009803921915590763, 'entity': {}}\n",
      "{'id': 3095, 'distance': 0.009708737954497337, 'entity': {}}\n",
      "{'id': 8525, 'distance': 0.009708737954497337, 'entity': {}}\n"
     ]
    }
   ],
   "source": [
    "from pymilvus import AnnSearchRequest\n",
    "\n",
    "# 复杂查询的实现\n",
    "# 多向量查询（注意和批量向量查询不同）\n",
    "# 多向量搜索使用hybrid_search() API在一次调用中执行多个 ANN 搜索请求。每个 AnnSearchRequest 代表特定矢量场上的单个搜索请求。\n",
    "# 示例创建两个 AnnSearchRequest 实例以对两个向量字段执行单独的相似性搜索。\n",
    "# 创建多搜索请求 filmVector\n",
    "\n",
    "# 准备第一个查询向量\n",
    "query_film_vector = [[0.19886812562848388, 0.06023560599112088, 0.6976963061752597, 0.2614474506242501,\n",
    "       0.838729485096104]]\n",
    "\n",
    "dense_search_params = {\n",
    "    'data': query_film_vector,\n",
    "    'anns_field': 'film_vector',\n",
    "    'param':{'metric_type': 'L2', 'nprobe': 10}, # nprobe代表访问簇的数量\n",
    "    'limit': 5\n",
    "}\n",
    "request1 = AnnSearchRequest(**dense_search_params)\n",
    "\n",
    "# 准备第二个查询向量\n",
    "query_poster_vector = [[0.19886812562848388, 0.06023560599112088, 0.6976963061752597, 0.2614474506242501,\n",
    "       0.838729485096104]]\n",
    "\n",
    "sparse_search_params = {\n",
    "    'data': query_poster_vector,\n",
    "    'anns_field': 'poster_vector',\n",
    "    'param':{'metric': 'COSINE'},\n",
    "    'limit': 5\n",
    "}\n",
    "\n",
    "request2 = AnnSearchRequest(**sparse_search_params)\n",
    "\n",
    "# 将两个搜索请求添加到一个列表中\n",
    "reqs = [request1, request2]\n",
    "\n",
    "ranker = RRFRanker(100)\n",
    "\n",
    "# 获取搜索结果\n",
    "res = client.hybrid_search(\n",
    "    collection_name='demo_v3',\n",
    "    reqs=reqs,\n",
    "    ranker=ranker,\n",
    "    limit=6\n",
    ")\n",
    "# 输出结果\n",
    "for hits in res:\n",
    "    print('TopK result:')\n",
    "    for hit in hits:\n",
    "        print(hit)"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2025-11-10T13:39:02.033636400Z",
     "start_time": "2025-11-10T13:39:02.004251100Z"
    }
   },
   "id": "a666c3785b84430c"
  },
  {
   "cell_type": "code",
   "execution_count": 57,
   "outputs": [],
   "source": [
    "client.drop_collection(collection_name=\"demo_v1\")\n",
    "client.drop_collection(collection_name=\"demo_v2\")\n",
    "client.drop_collection(collection_name=\"demo_v3\")"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2025-11-10T13:46:04.784837400Z",
     "start_time": "2025-11-10T13:46:04.727140400Z"
    }
   },
   "id": "7dc326833cd9d5f6"
  },
  {
   "cell_type": "code",
   "execution_count": 58,
   "outputs": [],
   "source": [
    "client.drop_database(db_name='milvus')"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2025-11-10T13:46:20.887430Z",
     "start_time": "2025-11-10T13:46:20.854220500Z"
    }
   },
   "id": "3f804e79ab673ec9"
  }
 ],
 "metadata": {
  "kernelspec": {
   "name": "edurag_py310",
   "language": "python",
   "display_name": "Python (EduRAG_py310)"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 2
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython2",
   "version": "2.7.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
